package com.topfun.controller;

import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.gson.Gson;
import com.topfun.dao.*;
import com.topfun.misc.MenuManager;
import com.topfun.sercurity.UserSecurity;
import com.topfun.utils.*;
import com.topfun.vo.*;
import com.topfun.vo.msgreq.TextMessage;
import com.topfun.vo.payment.ChargeOrder;
import com.topfun.vo.payment.WeChatOrder;
import com.topfun.vo.payment.WeChatOrderResult;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by huanga on 2017/9/10.
 * index
 */
@Controller
public class IndexController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(IndexController.class);


    @RequestMapping("/favicon.ico")
    public void favicon() {
    }

    @RequestMapping("/")
    public String index(Model model) {
        indexResponse(model);
        return "index";
    }

    @RequestMapping("/index.html")
    public String indexHtml(Model model) {
        indexResponse(model);
        return "index";
    }

    private void indexResponse(Model model) {
        Params        params      = ParamsDao.queryParamsByName("counter");
        List<Integer> counterList = new ArrayList<>();
        if (null != params) {
            List<String> counters = Splitter.on("|").omitEmptyStrings().splitToList(params.strValue);
            counters.forEach(counter -> counterList.add(Integer.parseInt(counter)));
        }
        model.addAttribute("counterList", counterList);
    }

    /**
     * 授权获取code
     *
     * @param redirect 微信回调url
     * @param wxstate  state
     * @param request  request
     * @param response response
     */
    @RequestMapping("/topfun/oauth2/authorize")
    public void oauth(String redirect, String wxstate,
                      HttpServletRequest request, HttpServletResponse response) {
        if (null != redirect && RegexUtil.isHttpURL(redirect)) {
            try {
                String authURL = String.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=%s#wechat_redirect",
                        Constants.WeChat_App_ID,
                        URLEncoder.encode(redirect, "UTF-8"),
                        URLEncoder.encode(StringUtil.isEmpty(wxstate) ? "" : wxstate, "UTF-8")
                );
                logger.debug(String.format("redirect:%s", authURL));
                response.sendRedirect(authURL);
            } catch (UnsupportedEncodingException e) {
                logger.error(String.format("Can't encode redirect url is %s", e.toString()));
                e.printStackTrace();
            } catch (IOException e) {
                logger.error(String.format("Can't encode redirect url is %s", e.toString()));
                e.printStackTrace();
            }
        }
    }

    /**
     * 用户登录
     * @param code code
     * @param req request
     * @param res response
     */
    @ResponseBody
    @RequestMapping("/topfun/user/login")
    public void userLogin(String code, HttpServletRequest req, HttpServletResponse res) {
        // 通过code换取网页授权access_token和openid
        long         a      = System.currentTimeMillis();
        OkHttpClient client = new OkHttpClient();
        String url = String.format(
                "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                Constants.WeChat_App_ID,
                Constants.WeChat_App_Secret,
                code
        );
        Request     request  = new Request.Builder().url(url).build();
        System.out.println(String.format("build request wx is %d ms",  System.currentTimeMillis() - a));
        WeChatOauth oauth;
        Response    response = null;
        try {
            response = client.newCall(request).execute();
            long b = System.currentTimeMillis();
            System.out.println(String.format("request wx is %d ms", b - a));
            if (!response.isSuccessful()) {
                logger.error(String.format("WeChat get access-token fail : %s", response.toString()));
                writeError(Code.ERR_AUTH_FROM_THIRD_RETURN_ERROR, req, res);
                return;
            }
            String body = response.body().string();
            logger.debug(String.format("WeChat get access-token return : %s", body));
            oauth = new Gson().fromJson(body, WeChatOauth.class);
            if (oauth.errcode != 0) {
                writeError(Code.ERR_AUTH_FROM_THIRD_RETURN_ERROR, req, res);
                return;
            }
        } catch (IOException e) {
            logger.error("WeChat get access-token error", e);
            writeError(Code.ERR_SERVICE_BUSY, req, res);
            return;
        } finally {
            if (response != null) {
                response.close();
            }
        }
        //拿openid去数据库判断用户是否存在
        if (!StringUtil.isEmpty(oauth.openid)) {
            User user = UserDao.queryUserByOpenId(oauth.openid);
            if (null != user) {
                //存在 刷新用户token 登录返回用户信息
                user.token = StringUtil.generateUUID();
                UserDao.updateUserToken(user.userId, user.token);
                writeResult(GsonUtil.toJson(user), req, res);
                return;
            } else {
                //如果不存在则调微信拉取用户信息(需scope为snsapi_userinfo)
                if (!StringUtil.isEmpty(oauth.access_token)) {
                    url = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN", oauth.access_token, oauth.openid);
                    request = new Request.Builder().url(url).build();
                    try {
                        response = client.newCall(request).execute();
                        if (!response.isSuccessful()) {
                            logger.error(String.format("WeChat get user-info fail : %s", response.toString()));
                            writeError(Code.ERR_GET_USER_FROM_THIRD_FAIL, req, res);
                            return;
                        }

                        String body = response.body().string();
                        logger.error(String.format("WeChat get user-info return : %s", body));
                        WeChatUser wxUser = new Gson().fromJson(body, WeChatUser.class);
                        if (wxUser.errcode == 0) {
                            //注册一个账号，然后返回用户信息
                            User newUser = buildRegisterUser(wxUser);
                            UserDao.insertUser(newUser);
                            writeResult(GsonUtil.toJson(user), req, res);
                            return;
                        } else {
                            writeError(Code.ERR_GET_USER_FROM_THIRD_RETURN_ERROR, req, res);
                            return;
                        }
                    } catch (IOException e) {
                        logger.error("WeChat get user-info error", e);
                        writeError(Code.ERR_SERVICE_BUSY, req, res);
                        return;
                    } finally {
                        if (response != null) {
                            response.close();
                        }
                    }
                }
            }
        }
        long c = System.currentTimeMillis();
        System.out.println(String.format("query db  is %d ms", c - a));
    }

    /**
     * 创建用户构造数据
     * @param wxUser wechat user
     * @return buildUser
     */
    private User buildRegisterUser(WeChatUser wxUser) {
        User user = new User();
        user.token = StringUtil.generateUUID();
        user.headImgUrl = wxUser.headimgurl;
        user.nickName = wxUser.nickname;
        user.openId = wxUser.openid;
        user.sex = wxUser.sex;
        return user;
    }

    /**
     * 兑换商品页面
     * @param m model
     * @return shop
     */
    @RequestMapping("/shop.html")
    public String shopHtml(Model m) {
        //兑换商品列表
        m.addAttribute("goodsList", GoodsDao.queryGoodsList());
        //中奖滚动
        m.addAttribute("sliderList", UserDao.queryBetPrizeSlider());
        return "shop";
    }

    /**
     * 商品兑换
     * @param userId userID
     * @param token token
     * @param goodsId goodsId
     * @param req request
     * @param res response
     */
    @ResponseBody
    @RequestMapping("/topfun/change/goods")
    public void changeGoods(long userId, String token, long goodsId, HttpServletRequest req, HttpServletResponse res) {
        boolean author = UserSecurity.isAuthorized(userId, token);
        if (author) {
            Goods goods  = GoodsDao.queryGoodsById(goodsId);
            int   number = goods.price / 100;//兑换number张100
            if (null == goods) {
                writeError(Code.ERR_NOT_FIND_GOODS, req, res);
                return;
            }
            //虚拟物品
            if (Goods.Type_Invented == goods.type) {
                //判断用户余额是否足够
                User user = UserDao.queryUserByUserId(userId);
                if (user.amount < (goods.changePrice * number)) {
                    writeError(Code.ERR_AMOUNT_NOT_ENOUGH, req, res);
                    return;
                }
                //判断兑换物品库存是否足够
                List<GoodsExtend> goodsExtends = GoodsDao.queryGoodsExtendByGoodsId(goodsId, number);
                if (null == goodsExtends || goodsExtends.size() < number) {
                    writeError(Code.ERR_GOODS_NOT_ENOUGH, req, res);
                    return;
                }
                //兑换商品
                UserDao.updateUserAmount(userId, user.amount - (goods.changePrice * number));//1.扣除用户乐豆
                List<Long> seqIds = new ArrayList<>();
                goodsExtends.forEach(goodsExtend -> seqIds.add(goodsExtend.seqId));
                String strSeqIds = Joiner.on(",").join(seqIds);
                GoodsDao.updateGoodsExtendStatus(strSeqIds, GoodsExtend.Status_Use);//2.修改卡密使用状态
                GoodsChangeRecord changeRecord = new GoodsChangeRecord(userId, goodsId, strSeqIds, 0);
                GoodsDao.insertGoodsChangeRecord(changeRecord);//3.发放兑换商品
                //更新商品库存
                GoodsDao.updateInventory(goodsId, number);
                //乐豆交易记录
                MarketRecord marketRecord = new MarketRecord(user, (goods.changePrice * number), String.format("兑换%s,兑换单个乐豆%d,兑换数量%d", goods.name, goods.changePrice, number), MarketRecord.STATUS_OUT, MarketRecord.TYPE_CHANGE_GOODS);
                MarketRecordDao.insertMarketRecord(marketRecord);
                writeSuccess(req, res);
            }
        } else {
            writeError(Code.ERR_INVALID_USER, req, res);
        }
    }

    /**
     * 跳转我的界面
     * @return me
     */
    @RequestMapping("/me.html")
    public String meHtml() {
        return "me";
    }

    /**
     * 用户兑换列表
     * @param userId userId
     * @param token token
     * @param req request
     * @param res response
     */
    @ResponseBody
    @RequestMapping("/topfun/user/changeGoods")
    public void userChangeGoods(long userId, String token, HttpServletRequest req, HttpServletResponse res) {
        boolean author = UserSecurity.isAuthorized(userId, token);
        if (author) {
            List<GoodsChangeRecord> list = GoodsDao.queryChangeRecordByUserId(userId);
            writeResult(GsonUtil.toJson(list), req, res);
        } else {
            writeError(Code.ERR_INVALID_USER, req, res);
        }
    }

    /**
     *跳转卡密页
     * @param goodsExtendIds 卡密id集合
     * @param model model
     * @return gift
     */
    @RequestMapping("/gift.html")
    public String giftHtml(String goodsExtendIds, Model model) {
        model.addAttribute("goodsExtendIds", goodsExtendIds);
        return "gift";
    }

    /**
     * ajax 获取卡密信息
     * @param userId userId
     * @param token token
     * @param goodsExtendIds 卡密id集合
     * @param req request
     * @param res response
     */
    @ResponseBody
    @RequestMapping("/topfun/look/key")
    public void lookKey(long userId, String token, String goodsExtendIds,
                        HttpServletRequest req, HttpServletResponse res) {
        boolean author = UserSecurity.isAuthorized(userId, token);
        if (author) {
            //该商品兑换用户才能查看卡密
            GoodsChangeRecord changeRecord = GoodsDao.queryChangeRecord(userId, goodsExtendIds);
            if (null == changeRecord) {
                writeError(Code.ERR_NOT_GOODS_CHANGE_USER, req, res);
                return;
            }
            List<GoodsExtend> goodsExtends = GoodsDao.queryGoodsExtendByIds(goodsExtendIds);
            writeResult(GsonUtil.toJson(goodsExtends), req, res);
        } else {
            writeError(Code.ERR_INVALID_USER, req, res);
        }
    }

    /**
     * 抽奖界面
     *
     * @param sort  orderId
     * @param model model
     * @return flip
     */
    @RequestMapping("/flip.html")
    public String flipHtml(long sort, Model model) {
        BetOrder betOrder = UserDao.queryBetOrderById(sort);
        if (null != betOrder) {
            betOrder.fillSort();
            model.addAttribute("betOrder", GsonUtil.toJson(betOrder));
        }
        return "flip";
    }

    /**
     * 投注
     * @param userId userId
     * @param token token
     * @param amount amount
     * @param req request
     * @param res response
     */
    @ResponseBody
    @RequestMapping("/topfun/bet/draw")
    public void betDraw(long userId, String token, int amount,
                        HttpServletRequest req, HttpServletResponse res) {
        if (amount < 10) {//投注金额错误
            writeError(Code.ERR_BET_AMOUNT_ERROR, req, res);
        } else {
            boolean author = UserSecurity.isAuthorized(userId, token);
            if (author) {
                User user = UserDao.queryUserByUserId(userId);
                if (user.amount < amount) { //用户账户金额不足
                    writeError(Code.ERR_AMOUNT_LACK, req, res);
                    return;
                } else {
                    int      number = MathUtils.random(100) + 1;//随机1-100
                    BetOrder betOrder;
                    if (number == 100) {
                        //一等奖:取数刚好为100
                        betOrder = new BetOrder(userId, amount, BetOrder.FIRST_WINNING_LEVEL, BetOrder.FIRST_PRIZE, BetOrder.AWARD_NO);
                    } else if (1 <= number && number <= 9) {
                        //二等奖:取数为1-9
                        betOrder = new BetOrder(userId, amount, BetOrder.TWO_WINNING_LEVEL, BetOrder.TWO_PRIZE, BetOrder.AWARD_NO);
                    } else if (10 <= number && number <= 53) {
                        //三等奖:取数为10-53
                        betOrder = new BetOrder(userId, amount, BetOrder.THREE_WINNING_LEVEL, BetOrder.THREE_PRIZE, BetOrder.AWARD_NO);
                    } else {
                        //未中奖
                        betOrder = new BetOrder(userId, amount);
                    }
                    //扣除投注金币
                    if (UserDao.updateUserAmount(userId, user.amount - amount) > 0) {
                        user.amount = user.amount - amount;
                        //保存订单
                        betOrder = UserDao.insertBetOrder(betOrder);
                        //交易记录
                        MarketRecord marketRecord = new MarketRecord(user, amount, "投注金币扣除", MarketRecord.STATUS_OUT, MarketRecord.TYPE_BET);
                        MarketRecordDao.insertMarketRecord(marketRecord);
                    }
                    logger.info(String.format("topfun bet draw ! userId:%d \t sort:%s",userId,GsonUtil.toJson(betOrder.sort)));
                   /* //如果中奖发奖
                    if (betOrder.bonus > 0) {
                        //发奖
                        UserDao.updateBetOrderAward(betOrder.orderId, BetOrder.AWARD_YES);
                        UserDao.updateUserAmount(betOrder.userId, user.amount + betOrder.bonus);
                        //交易记录
                        MarketRecord marketRecord = new MarketRecord(user, betOrder.bonus, "投注中奖金币返奖", MarketRecord.STATUS_IN, MarketRecord.TYPE_GRANT_PRIZE);
                        MarketRecordDao.insertMarketRecord(marketRecord);
                    }*/
                    writeResult(GsonUtil.toJson(betOrder), req, res);
                }
            } else {
                writeError(Code.ERR_INVALID_USER, req, res);
            }
        }
    }

    /**
     * 投注中奖发奖
     * @param userId userId
     * @param token token
     * @param orderId orderId
     * @param req request
     * @param res response
     */
    @RequestMapping("/topfun/grant/prize")
    public void grantPrize(long userId, String token, long orderId,
                        HttpServletRequest req, HttpServletResponse res) {
        if(orderId < 0 ){//投注金额错误
            writeError(Code.ERR_INVALID_PARAMETERS,req,res);
            return;
        }else{
            Code code = UserSecurity.authorized(userId,token);
            if(code == Code.SUCCESS){
                BetOrder betOrder = UserDao.queryBetOrderById(orderId);
                if(null == betOrder){
                    //订单不存在
                    writeError(Code.ERR_ORDER_NOT_FOUND,req,res);
                    return;
                }else{
                    //是否中奖
                    if(betOrder.winningLevel == BetOrder.NOT_WINNING){
                        writeError(Code.ERR_BET_NOT_WINNING,req,res);
                        return;
                    }
                    //是否已经领奖
                    if(betOrder.award == BetOrder.AWARD_YES){
                        writeError(Code.ERR_ALREADY_GRANT_PRIZE,req,res);
                        return;
                    }
                    //发奖
                    UserDao.updateBetOrderAward(orderId,BetOrder.AWARD_YES);
                    User user = UserDao.queryUserByUserId(betOrder.userId);
                    user.amount =user.amount + betOrder.bonus;
                    UserDao.updateUserAmount(betOrder.userId,user.amount);
                    //交易记录
                    MarketRecord marketRecord = new MarketRecord(user,betOrder.bonus,"投注中奖金币返奖",MarketRecord.STATUS_IN,MarketRecord.TYPE_GRANT_PRIZE);
                    MarketRecordDao.insertMarketRecord(marketRecord);
                    writeResult(GsonUtil.toJson(user), req, res);
                }
            }else {
                writeError(Code.ERR_INVALID_USER, req, res);
            }
        }
    }

    /**
     * 充值订单创建
     * @param pOrder 订单信息
     * @param req request
     * @param res response
     */
    @ResponseBody
    @RequestMapping("/topfun/payment/create")
    public void paymentCreate(ChargeOrder pOrder, HttpServletRequest req, HttpServletResponse res) {
        int amount = ConfigLoadUtil.isDebug() ? 1 : 100;//测试环境最少1分，正式最少1块
        if (pOrder.userId <= 0 || StringUtil.isEmpty(pOrder.token) || StringUtil.isEmpty(pOrder.openId) || pOrder.amount < amount || StringUtil.isEmpty(pOrder.subject) || StringUtil.isEmpty(pOrder.description) || pOrder.payType != 1) {
            logger.error(String.format("request params is error ! order:%s", GsonUtil.toJson(pOrder)));
            writeError(Code.ERR_MISS_PARAMETERS, req, res);
        }
        boolean author = UserSecurity.isAuthorized(pOrder.userId, pOrder.token);
        if (!author) {
            writeError(Code.ERR_INVALID_USER, req, res);
            return;
        }
        pOrder.orderId = String.format("%d", Constants.generateOrderID());// 订单ID, 唯一键
        pOrder.orderTime = DateUtil.getDateTimeString(); // 下单时间
        pOrder.ip = StringUtil.isEmpty(pOrder.ip) ? "0.0.0.0" : pOrder.ip;
        // 微信统一下单
        WeChatOrder wxOrder = new WeChatOrder();
        Code        code    = WeChatPayUtil.buildWechatOrder(pOrder, wxOrder);
        if (code != Code.SUCCESS) {
            logger.error("WeChatPayUtil buildWechatOrder error.");
            writeError(code, req, res);
            return;
        }
        WeChatOrderResult result = WeChatPayUtil.unifiedOrder(wxOrder);
        if (result == null) {
            logger.error("WeChatPayUtil unifiedOrder error .");
            writeError(Code.ERR_THIRD_PAY_SYSTEM_BUSY, req, res);
            return;
        }
        // 覆盖 pConfirm 内容
        pOrder.payInfo = WeChatPayUtil.generatePayInfo(result);
        //订单入库
        PaymentDao.insertChargeOrder(pOrder);
        writeResult(GsonUtil.toJson(pOrder), req, res);
    }

    /**
     * 充值回调通知
     * @param request request
     * @param response response
     */
    @ResponseBody
    @RequestMapping("/topfun/payment/notify")
    public void paymentNotify(HttpServletRequest request, HttpServletResponse response) {
        Code code = WeChatPayUtil.parse(request);
        try {
            response.getWriter().write(WeChatPayUtil.response(Code.SUCCESS == code));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 用户信息刷新
     * @param userId userId
     * @param token token
     * @param request request
     * @param response response
     */
    @RequestMapping("/topfun/user/refersh")
    public void userRefersh(long userId, String token,
                            HttpServletRequest request, HttpServletResponse response) {
        Code code = UserSecurity.authorized(userId, token);
        if (code == Code.SUCCESS) {
            User user = UserDao.queryUserByUserId(userId);
            writeResult(GsonUtil.toJson(user), request, response);
            return;
        }
        writeError(code, request, response);
    }

    /**
     * 微信事件-关注
     */
    @RequestMapping("/topfun/wechat/event")
    public void wechatEvent(HttpServletRequest request, HttpServletResponse response) {
        //==========================
        //接口配置信息验证，使用一次
        //==========================
        boolean isGet = request.getMethod().toLowerCase().equals("get");
        if (isGet) {
            String signature = request.getParameter("signature"); // 微信加密签名，signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
            String timestamp = request.getParameter("timestamp");   // 时间戳
            String nonce     = request.getParameter("nonce");  // 随机数
            String echostr   = request.getParameter("echostr");    // 随机字符串
            // 通过检验signature对请求进行校验，若校验成功则原样返回echostr，否则接入失败
            if (SignUtil.checkSignature(signature, timestamp, nonce)) {
                try {
                    response.getWriter().write(echostr);
                    return;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else {
            //==========================
            //处理微信服务器发来的消息
            //==========================
            // xml请求解析
            Map<String, String> requestMap = null;
            try {
                requestMap = MessageUtil.parseXml(request);
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 消息类型
            String msgType = requestMap.get("MsgType");
            //mstType = event
            if ((msgType.equals(WechatMessageUtil.REQ_MESSAGE_TYPE_EVENT))) {
                String eventType = requestMap.get("Event");
                String openId    = requestMap.get("FromUserName");//发送方帐号（一个OpenID）
                User   user      = UserDao.queryUserByOpenId(openId);
                if (null != user) {
                    if (eventType.equals(WechatMessageUtil.EVENT_TYPE_SUBSCRIBE)) {
                        // 关注
                        user.favorited = User.FAVORITED_TRUE;
                        UserDao.updateUserFavorited(user.userId, user.favorited);
                        // 发送方帐号（open_id）
                        String fromUserName = requestMap.get("FromUserName");
                        // 公众帐号
                        String toUserName = requestMap.get("ToUserName");
                        //这里 from 和 to 要转换发送
                        TextMessage textMessage = new TextMessage(fromUserName,toUserName,"项目测试中 敬请期待，有问题 请直接微信对话或客服QQ 254003566");
                        try {
                            response.getWriter().write(MessageUtil.messageToXml(textMessage));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        return;
                    } else if (eventType.equals(WechatMessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {
                        //取消关注
                        user.favorited = User.FAVORITED_FALSE;
                        UserDao.updateUserFavorited(user.userId, user.favorited);
                    }
                }

                //微信菜单点击
                if(eventType.equalsIgnoreCase(WechatMessageUtil.EVENT_TYPE_CLICK)){
                    String eventKey = requestMap.get("EventKey");
                    if(eventKey.equals(MenuManager.Customer_Service_Key)){
                        logger.debug("response click ....");
                        try {
                            // 发送方帐号（open_id）
                            String fromUserName = requestMap.get("FromUserName");
                            // 公众帐号
                            String toUserName = requestMap.get("ToUserName");
                            //这里 from 和 to 要转换发送
                            TextMessage textMessage = new TextMessage(fromUserName,toUserName,"直接发送消息给公众号，将会有客服联系您。");
                            response.getWriter().write(MessageUtil.messageToXml(textMessage));
                            return;
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        writeSuccess(request, response);
    }

    /**
     * 新人奖励
     * @param userId userId
     * @param token token
     * @param request request
     * @param response response
     */
    @RequestMapping("/topfun/user/rookieAward")
    public void rookieAward(long userId, String token,
                            HttpServletRequest request, HttpServletResponse response) {
        Code code = UserSecurity.authorized(userId,token);
        if(code == Code.SUCCESS){
            User user = UserDao.queryUserByUserId(userId);
            if(user.favorited ==User.FAVORITED_TRUE && user.rookieAward == User.ROOKIEAWARD_FALSE){//如果用户关注未领取新人奖励
                Params params = ParamsDao.queryParamsByName("rookieAward");
                //发放新人奖励 -金币
                int amount = params != null?params.intValue:0;
                if(amount > 0) {
                    int result = UserDao.updateUserAmount(user.userId, user.amount+amount);
                    if (result > 0) {
                        MarketRecord marketRecord = new MarketRecord(user,amount,"新人奖励发放",MarketRecord.STATUS_IN,MarketRecord.TYPE_NEW_USER_REWARD);
                        MarketRecordDao.insertMarketRecord(marketRecord);
                    } else {
                        writeError(Code.ERR_SERVICE_BUSY,request,response);
                        return;
                    }
                }
                if(code == Code.SUCCESS){
                    //发放成功 修改用户领取新人奖励状态
                    UserDao.updateUserRookieAward(userId,User.ROOKIEAWARD_TRUE);
                    user.rookieAward = User.ROOKIEAWARD_TRUE;
                    user.amount = user.amount + (params != null?params.intValue:0);
                }
            }else{
                writeError(Code.ERR_NEW_USER_AWARD,request,response);
                return;
            }
            writeResult(GsonUtil.toJson(user),request,response);
        }else{
            writeError(code,request,response);
        }

    }

    /**
     * 新人引导完成
     * @param userId userId
     * @param token token
     * @param request request
     * @param response response
     */
    @RequestMapping("/topfun/noviceBoot/finish")
    public void noviceBootFinish(long userId, String token,
                            HttpServletRequest request, HttpServletResponse response) {
        Code code = UserSecurity.authorized(userId,token);
        if(code == Code.SUCCESS){
            UserDao.updateUserNoviceBoot(userId,User.NOVICEBOOT_TRUE);
            writeSuccess(request,response);
        }else{
            writeError(code,request,response);
        }
    }

    /**
     * 卡密说明
     * @return string
     */
    @RequestMapping("/explain.html")
    public String explain() {
        return "explain";
    }

}
